package com.shenchuangit.rydemo.web.system.sequence.service.impl;

import java.util.List;

import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.shenchuangit.rydemo.web.system.sequence.mapper.SequenceMapper;
import com.shenchuangit.rydemo.web.system.sequence.domain.Sequence;
import com.shenchuangit.rydemo.web.system.sequence.service.ISequenceService;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.SecurityUtils;

/**
 * 序列Service业务层处理
 *
 * @author liuyu
 * @date 2021-06-10
 */
@Service
public class SequenceServiceImpl implements ISequenceService {
    @Autowired
    private SequenceMapper sequenceMapper;

    /**
     * 查询序列
     *
     * @param id 序列ID
     * @return 序列
     */
    @Override
    public Sequence selectSequenceById(Long id) {
        return sequenceMapper.selectSequenceById(id);
    }

    /**
     * 查询序列列表
     *
     * @param sequence 序列
     * @return 序列
     */
    @Override
    public List<Sequence> selectSequenceList(Sequence sequence) {
        return sequenceMapper.selectSequenceList(sequence);
    }

    /**
     * 新增序列
     *
     * @param sequence 序列
     * @return 结果
     */
    @Override
    public int insertSequence(Sequence sequence) {

        //权限相关字段赋值
        SysUser loginUser = SecurityUtils.getLoginUser().getUser();
        sequence.setCreateBy(loginUser.getUserName());
        return sequenceMapper.insertSequence(sequence);
    }

    /**
     * 修改序列
     *
     * @param sequence 序列
     * @return 结果
     */
    @Override
    public int updateSequence(Sequence sequence) {
        return sequenceMapper.updateSequence(sequence);
    }

    /**
     * 批量删除序列
     *
     * @param ids 需要删除的序列ID
     * @return 结果
     */
    @Override
    public int deleteSequenceByIds(Long[] ids) {
        return sequenceMapper.deleteSequenceByIds(ids);
    }

    /**
     * 删除序列信息
     *
     * @param id 序列ID
     * @return 结果
     */
    @Override
    public int deleteSequenceById(Long id) {
        return sequenceMapper.deleteSequenceById(id);
    }

    /**
     * 根据序列名称获取当前序列值
     * @param seqName 序列名称
     * @return 序列值 String
     */
    @Override
    public String getNextSeq(String seqName) {
        Sequence search = new Sequence();
        search.setSeqName(seqName);
        //下一个值
        long nextValue = 0L;
        List<Sequence> sequenceList = this.sequenceMapper.selectSequenceList(search);
        if (sequenceList.size() == 1) {
            Sequence currentSeq = sequenceList.get(0);

            Long currentValue = currentSeq.getCurrentValue();
            Integer increment = currentSeq.getIncrement();
            Long seqMax = currentSeq.getSeqMax();
            boolean cycle = currentSeq.getCycle() == 1;

            if (null == currentValue) {
                throw new CustomException("序列名称为" + seqName + "的序列，序列当前值为null，请检查配置！");
            }
            if (null == increment) {
                throw new CustomException("序列名称为" + seqName + "的序列，序列增量为null，请检查配置！");
            }
            if (null != seqMax) {
                // 判断是否超过序列最大值
                if (seqMax > currentValue + increment) {
                    // 如果没有超过最大值，根据增量更新最大值
                    nextValue = currentValue + increment;
                    // 如果超过最大值，判断是否循环
                }  else {
                    // 如果序列循环，序列从1开始
                    if (cycle) {
                        nextValue = 1L;
                        // 如果不循环，抛出异常
                    } else {
                        throw new CustomException("数据库未配置名称为" + seqName + "的不循环序列达到序列值最大值，请联系管理员更新！");
                    }
                }
            } else {
                nextValue = currentValue + increment;
            }

            // 更新保存增加过的当前序列
            currentSeq.setCurrentValue(nextValue);
            this.sequenceMapper.updateSequence(currentSeq);

        } else if (sequenceList.size() == 0) {
            throw new CustomException("数据库未配置名称为" + seqName + "的序列！");
        } else {
            throw new CustomException("数据库配置多个名称为" + seqName + "的序列，请检查！");
        }

        return String.valueOf(nextValue);
    }

    /**
     * 获取序列号（默认序列长度4位）
     * @param prefix 字母前缀
     * @param seqName 序列名称
     * @return 序列值
     */
    @Override
    public String getSerialNumber(String prefix, String seqName) {
        String dateStr = DateUtils.dateTimeNow("yyyyMMddHH");
        String seqNumStr = this.getNextSeq(seqName);
        int len = seqNumStr.length();
        StringBuilder subStr = new StringBuilder();
        if (len < 4) {
            for (int i = 0; i < 4-len; i++) {
                subStr.append(0);
            }
        }
        subStr.append(seqNumStr);
        return prefix + dateStr + subStr;
    }

    /**
     * 获取序列号
     * @param prefix 字母前缀
     * @param seqName 序列名称
     * @param strLength 序列字符长度
     * @return 序列值
     */
    @Override
    public String getSerialNumber(String prefix, String seqName, int strLength) {
        String dateStr = DateUtils.dateTimeNow("yyyyMMddHH");
        String seqNumStr = this.getNextSeq(seqName);
        int len = seqNumStr.length();
        StringBuilder subStr = new StringBuilder();
        if (len < strLength) {
            for (int i = 0; i < strLength-len; i++) {
                subStr.append(0);
            }
        }
        subStr.append(seqNumStr);
        return prefix + dateStr + subStr;
    }

    /**
     * 获取序列号（默认序列长度4位）
     * @param seqName 序列名称
     * @return 序列值
     */
    @Override
    public String getSerialNumber(String seqName) {
        String dateStr = DateUtils.dateTimeNow("yyyyMMddHH");
        String seqNumStr = this.getNextSeq(seqName);
        int len = seqNumStr.length();
        StringBuilder subStr = new StringBuilder();
        if (len < 4) {
            for (int i = 0; i < 4-len; i++) {
                subStr.append(0);
            }
        }
        subStr.append(seqNumStr);
        return dateStr + subStr;
    }

    /**
     * 获取序列号
     * @param seqName 序列名称
     * @param strLength 序列字符长度
     * @return 序列值
     */
    @Override
    public String getSerialNumber(String seqName, int strLength) {
        String dateStr = DateUtils.dateTimeNow("yyyyMMddHH");
        String seqNumStr = this.getNextSeq(seqName);
        int len = seqNumStr.length();
        StringBuilder subStr = new StringBuilder();
        if (len < strLength) {
            for (int i = 0; i < strLength-len; i++) {
                subStr.append(0);
            }
        }
        subStr.append(seqNumStr);
        return dateStr + subStr;
    }
}
